package cn.com.greatwall.system.modules.oauth2.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

import cn.com.greatwall.system.modules.security.service.UserDetailsServiceImpl;

/**
 * @Author herw
 * @Time 2020-10-24 11:33:24
 * @Version 1.0
 * @Description: TODO(用一句话描述该文件做什么)
 */
@Configuration
@ConditionalOnProperty(name = "sos.token.store", havingValue = "jwt")
public class JwtTokenStoreConfig {
    /**
     * HMAC key, default: IH6S2dhCEMwGr7uE4fBakSuDh9SoIrRa alg: HMACSHA256
     */
    @Value("${sos.token.store.jwt.key:IH6S2dhCEMwGr7uE4fBakSuDh9SoIrRa}")
    private String jwtKey;

    @Bean
    public JwtAccessTokenConverter accessTokenConverter(UserDetailsServiceImpl userDetailsService) {
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();

        DefaultAccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
        DefaultUserAuthenticationConverter userAuthenticationConverter = new DefaultUserAuthenticationConverter();
        userAuthenticationConverter.setUserDetailsService(userDetailsService);
//        userAuthenticationConverter.setDefaultAuthorities(new String[]{"USER"});
        tokenConverter.setUserTokenConverter(userAuthenticationConverter);

        tokenConverter.setIncludeGrantType(true);
//        tokenConverter.setScopeAttribute("_scope");
        jwtAccessTokenConverter.setAccessTokenConverter(tokenConverter);

        jwtAccessTokenConverter.setSigningKey(this.jwtKey);
        return jwtAccessTokenConverter;
    }
    
    /**
     * JWT TokenStore
     * 
     * @param jwtAccessTokenConverter
     * @return
     */
    @Bean
    public TokenStore tokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
        return new JwtTokenStore(jwtAccessTokenConverter);
    }
    
    @Bean
    public DefaultTokenServices tokenServices(TokenStore tokenStore, JwtAccessTokenConverter tokenEnhancer, ClientDetailsService clientDetailsService) {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setTokenStore(tokenStore);
        tokenServices.setClientDetailsService(clientDetailsService);
        //  support refresh token
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setTokenEnhancer(tokenEnhancer);
        return tokenServices;
    }
}
